/*
 * @Author: “ygnnli” “1585923072@qq.com”
 * @Date: 2024-08-04 17:38:08
 * @LastEditors: “ygnnli” “1585923072@qq.com”
 * @LastEditTime: 2024-08-05 10:09:59
 * @FilePath: /110/54/net_cal/TcpServerMain.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <functional>
#include <memory>
#include "Protocol.hpp"
#include "TcpServer.hpp"
#include "CalCulate.hpp" // 计算模块

using namespace protocol_ns;

// 输入格式不对
void Usage(std::string proc)
{
    std::cout << "Usage: \n\t" << proc << "local_port\n"
              << std::endl;
}

using callback_t = std::function<Response(const Request &req)>; // 定义回调函数类型

class Service
{
public:
    Service(callback_t cb) : _cb(cb)
    {
    }

    // 传入一个socket指针和客户端地址
    void ServiceHelper(socket_sptr sockptr, InetAddr client)
    {
        int sockfd = sockptr->SockFd();
        LOG(DEBUG, "get a new link,info %s:%d, fd : %d\n", client.IP().c_str(), client.Port(), sockfd); // 获取客户端信息
        std::string clientaddr = "[" + client.IP() + ":" + std::to_string(client.Port()) + "] ";        // 获取客户端信息
        std::string inbuffer;                                                                           // 用来存储接收到的数据
        while (1)
        {
            sleep(5);
            Request req;
            // 你怎么保证一个大的字符串里面有没有完整的请求
            // 1.
            int n = sockptr->Recv(&inbuffer); // 将接收到的数据存储到inbuffer中
            if (n < 0)
            {
                LOG(DEBUG, "client %s close\n", clientaddr.c_str()); // 客户端关闭
                break;
            }
            std::cout << "inbuffer: " << inbuffer << std::endl;//中已经存了多少数据
            // 2. 分析数据，确认完整报文
            std::string package; // 存储完整报文
            while (1)
            {
                package = Decode(inbuffer); // 解码
                if (package.empty())
                    break; // 如果解码失败，则跳出循环

                std::cout << "---------------begin----------------" << std::endl;

                std::cout << "resq string: \n"
                          << package << std::endl; // 打印接收到的一串完整编码

                // 得到了一个完整的包
                // 我敢保证，你一定读到了一个完整的json串.
                // 3.反序列化
                req.Deserialize(package); // 反序列化

                // 4. 业务处理
                Response resp = _cb(req);

                // 5. 对应答做序列化
                std::string send_str;
                resp.Serialize(&send_str);

                std::cout << "resp Serialize: " << std::endl;
                std::cout << send_str << std::endl; // 打印序列化后的数据

                // 6. 添加长度报头
                send_str = Encode(send_str);
                std::cout << "resp Encode: " << std::endl;
                std::cout << send_str << std::endl; // 打印序列化后的数据

                // "len"\r\n"{             }"\r\n"
                sockptr->Send(send_str); // 发送数据  暂时不对发送做处理
            }
        }
    }

private:
    callback_t _cb; // 回调函数
};

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        return 1;
    }
    uint16_t port = std::atoi(argv[1]);

    CalCulate cal;                                                                  // 计算模块
    Service calservice(std::bind(&CalCulate::Excute, &cal, std::placeholders::_1)); // 绑定回调函数

    io_service_t service = std::bind(&Service::ServiceHelper, &calservice, std::placeholders::_1, std::placeholders::_2); // 绑定回调函数

    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(port, service);

    tsvr->Loop(); // 启动服务

    return 0;
}
